#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<dirent.h>
#include<sys/stat.h>
#include<time.h>
#include<unistd.h>

#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include <sstream> 
#include<random> 
using namespace std;

class Judge{

public:

    vector<vector<string>> output_file;


    Judge(){
        first_in_dir = true;
    }



    ~Judge(){
        while (!output_file.empty()){
            while(!(*output_file.begin()).empty())
                (*output_file.begin()).erase((*output_file.begin()).begin());
            output_file.erase(output_file.begin());
        }
    }



    void travel_dir(const char* path){
        DIR *d;
        struct dirent* file = new dirent();
        struct stat* st = new struct stat();
        if(!(d = opendir(path))){ // 打不开指定的起始文件夹
            printf("erroe dirs %s!!!\n", path);
            return;
        }

        while((file = readdir(d)) != NULL){
            // 跳过隐藏文件, 当前目录(.),或上一级目录
            if(strncmp(file->d_name, ".", 1) == 0)
                continue;
            //如果是普通的文件
            if(file->d_type == 8){

                string file_name = file->d_name;

                if(strncmp(file_name.substr(file_name.length()-3,file_name.length()).c_str(), \
                           "cpp", 3) == 0){
                    
                    file_name = file_name.substr(0, file_name.length()-4);
                    
                    char* output_file_path = (char *)malloc(strlen(path) + strlen(file->d_name) + 2);
                    memset(output_file_path, '\0', sizeof(output_file_path));
                    strcat(output_file_path, path);
                    strcat(output_file_path, "/");
                    strcat(output_file_path, file_name.c_str());

                    std::ifstream ifs_check;
                    ifs_check.open(string(output_file_path)+".txt", std::ios::in);
                    if (ifs_check.is_open()){
                        if(first_in_dir){
                            vector<string> temp;
                            output_file.push_back(temp);
                            first_in_dir = false;
                        }
                        output_file.back().push_back(output_file_path);
                    }
                }
            }
            //如果是文件夹
            if(file->d_type == 4){
                char* dir_path = (char *)malloc(strlen(path) + strlen(file->d_name) + 2);
                memset(dir_path, '\0', sizeof(dir_path));
                strcat(dir_path, path);
                strcat(dir_path, "/");
                strcat(dir_path, file->d_name);
                first_in_dir = true;
                travel_dir(dir_path);
            }
        }
        closedir(d);
        return;
    }



    vector<vector<vector<bool>>> judge(){
        vector<vector<vector<bool>>> judge_result;
        for(vector<vector<string>>::iterator dirIt = output_file.begin(); dirIt != output_file.end(); dirIt++){
            vector<vector<bool>> dir_judge;
            judge_result.push_back(dir_judge);
            for(vector<string>::iterator output_fileIt1 = (*dirIt).begin(); output_fileIt1 != (*dirIt).end(); output_fileIt1++){
                vector<bool> file1;
                judge_result.back().push_back(file1);
                for(vector<string>::iterator output_fileIt2 = (*dirIt).begin(); output_fileIt2 != (*dirIt).end(); output_fileIt2++){

                    std::ifstream in1((*output_fileIt1)+".txt");
                    std::ifstream in2((*output_fileIt2)+".txt");
                    std::stringstream  tmp1;
                    std::stringstream  tmp2;

                    tmp1 << in1.rdbuf();
                    tmp2 << in2.rdbuf();

                    std::string str1 = tmp1.str();
                    std::string str2 = tmp2.str();

                    judge_result.back().back().push_back(strcmp(str1.c_str(), str2.c_str()) == 0);

                }
            }
        }
        return judge_result;
    }
private:
    bool first_in_dir; 
};

// int main(){
//     Judge *judge = new Judge();
//     judge->travel_dir("./input");
//     judge->judge();
//     delete judge;

//     return 0;
// }